Concurrency errors are difficult problems for developers writing multi-threaded applications to solve. Even expert programmers have difficulty predicting complicated behaviors resulting from the unexpected interaction of operations in different threads. Three exemplary types of concurrency errors are data races, atomicity violations, and ordering violations. Data races occur when two or more memory operations in different threads, at least one of which is a write, access the same memory location and are not properly synchronized. Atomicity violations happen when memory operations assumed to be executed atomically are not enclosed inside a single critical section. Ordering violations happen when memory accesses in different threads happen in an unexpected order. Some particularly difficult concurrency errors to resolve involve multiple variables. Though some efforts have been made to individually detect data races, locking discipline violations, and atomicity violations, what is needed are automated systems and methods for finding general concurrency errors, including multivariable errors and ordering violations.